<template>
  <div class="build">
    <contentmenu ref="contentmenu"></contentmenu>
    <imglist ref="imglist" @change="handleSetimg"></imglist>
    <headers ref="headers"></headers>
    <top ref="top"></top>
    <div class="app" :class="{ 'app--none': !menuFlag }">
      <div class="menu" :style="{ width: setPx(this.menuParams.menuWidth) }" v-show="menuFlag && menuShow"
        @click.self="handleInitActive">
        <div class="menu__drag" ref="menuDrag" @mousedown="handleDrag($event, 'menu')"></div>
        <div class="menu_header  title">
          <div class="title_box">
            图层
            <div class="title_menu">
              <div class="head_btn" :class="{ 'head_btn--active': layerType == 0 }" @click="layerType = 0">
                <i class="el-icon-monitor"></i>
              </div>
              <div class="head_btn" :class="{ 'head_btn--active': layerType == 1 }" @click="layerType = 1">
                <i class="el-icon-coin"></i>
              </div>
            </div>
          </div>
        </div>
        <el-scrollbar class="menu__scrollbar">
          <layer ref="layer" :type="layerType" style="padding:0 5px;" :nav="nav"></layer>
        </el-scrollbar>
      </div>
      <!-- 中间区域 -->
      <div ref="section" @contextmenu.prevent="() => { }" class="section">
        <div class="refer-line-img" @click="imgClick">
          <img :src="isShowReferLine ? imgOpenData : imgClose">
        </div>
        <sketch-rule :thick="thick" :scale="scale" :width="width" :height="height" :startX="startX" :startY="startY"
          :isShowReferLine="isShowReferLine" :palette="palette" :shadow="shadow" :horLineArr="lines.h"
          :verLineArr="lines.v" />
        <div ref='screensRef' class="screens" @mousedown="handleInitActive" @wheel="handleWheel" @scroll="handleScroll">
          <div ref="containerRef" class="screen-container">
            <div class="canvas" ref="canvas" :style="canvasStyle">
              <container ref="container" :wscale="scale"></container>
            </div>
          </div>
        </div>
      </div>
      <div class="menu params" :style="{ width: setPx(this.menuParams.paramsWidth) }" v-show="menuFlag && paramsShow">
        <div class="menu__drag" ref="paramsDrag" @mousedown="handleDrag($event, 'params')" :style="{ left: '-4px' }">
        </div>
        <div class="menu_header ">
          <el-tabs v-if="isMain" class="menu__tabs" @tab-click="handleTabClick" stretch v-model="menuTabs">
            <el-tab-pane name="0">
              <span slot="label"><i class="el-icon-setting"></i>配置</span>
            </el-tab-pane>
            <!-- 数据配置 -->
            <el-tab-pane name="1" v-if="validProp('dataList')">
              <span slot="label"><i class="el-icon-document-copy"></i>数据</span>
            </el-tab-pane>
            <!-- 交互事件配置 -->
            <el-tab-pane name="2" v-if="validProp('eventList')">
              <span slot="label"><i class="el-icon-thumb"></i>交互</span>

            </el-tab-pane>
            <!-- 其他事件配置 -->
            <el-tab-pane name="3" v-if="!isFolder">
              <span slot="label"><i class="el-icon-mouse"></i>事件</span>
            </el-tab-pane>
            <!-- 基本参数配置 -->
            <el-tab-pane name="4">
              <span slot="label"><i class="el-icon-folder"></i>参数</span>
            </el-tab-pane>
          </el-tabs>
          <p class="title">{{ isMain ? `${activeObj.title}（${activeObj.name}）` : '配置 ' }}</p>
        </div>
        <el-scrollbar class="menu__scrollbar" :style="scrollStyleName">
          <template v-if="menuTabs == 0">
            <el-form label-width="110px" label-position="left" size="small">

              <!-- 多选配置选项 -->
              <template v-if="isSelectActive">
                <el-form-item label="水平方式">
                  <el-tooltip content="左对齐" placement="top">
                    <i class="el-icon-s-fold icon" @click="$refs.container.handlePostionSelect('left')"></i>
                  </el-tooltip>
                  <el-tooltip content="居中对齐" placement="top">
                    <i class="el-icon-s-operation icon" @click="$refs.container.handlePostionSelect('center')"></i>
                  </el-tooltip>
                  <el-tooltip content="右对齐" placement="top">
                    <i class="el-icon-s-unfold icon" @click="$refs.container.handlePostionSelect('right')"></i>
                  </el-tooltip>
                </el-form-item>
                <el-form-item label="垂直方式">
                  <el-tooltip content="顶对齐" placement="top">
                    <i class="el-icon-s-fold icon" @click="$refs.container.handlePostionSelect('top')"></i>
                  </el-tooltip>
                  <el-tooltip content="中部对齐" placement="top">
                    <i class="el-icon-s-operation icon" @click="$refs.container.handlePostionSelect('middle')"></i>
                  </el-tooltip>
                  <el-tooltip content="底对齐" placement="top">
                    <i class="el-icon-s-unfold icon" @click="$refs.container.handlePostionSelect('bottom')"></i>
                  </el-tooltip>
                </el-form-item>
                <el-form-item label-width="0">
                  <el-button type="primary" size="small" class="block" @click="handleFolder">成组</el-button>
                </el-form-item>
                <el-form-item label-width="0">
                  <el-button type="danger" size="small" class="block" @click="handleDeleteSelect">删除</el-button>
                </el-form-item>
              </template>
              <!-- 组件配置 -->
              <template v-else-if="activeIndex">
                <el-form-item label="图层名称">
                  <avue-input v-model="activeObj.name"></avue-input>
                </el-form-item>
                <template v-if="!isFolder">
                  <el-form-item label="隐藏">
                    <avue-switch v-model="activeObj.display"></avue-switch>
                  </el-form-item>
                  <el-form-item label="锁定">
                    <avue-switch v-model="activeObj.lock"></avue-switch>
                  </el-form-item>
                </template>
                <template v-if="validProp('colorList')">
                  <el-form-item label="系统配色">
                    <avue-switch v-model="activeOption.switchTheme"></avue-switch>
                  </el-form-item>
                </template>
                <component :is="activeComponent.prop + 'Option'"></component>
                <main-option></main-option>
              </template>
              <!-- 主屏的配置项 -->
              <template v-else>
                <el-form-item label="大屏大小">
                  <div class="flex">
                    <avue-input-number v-model="config.width"></avue-input-number>
                    &nbsp;x&nbsp;
                    <avue-input-number v-model="config.height"></avue-input-number>
                  </div>
                </el-form-item>
                <el-form-item label="大屏简介">
                  <avue-input v-model="config.info" type="textarea" :min-rows="5"></avue-input>
                </el-form-item>
                <el-form-item label="背景颜色">
                  <avue-input-color v-model="config.backgroundColor"></avue-input-color>
                </el-form-item>
                <el-form-item label="背景图片">
                  <img :src="config.backgroundImage" @click="handleOpenImg('config.backgroundImage', 'background')" alt=""
                    width="100%" />
                  <el-input clearable v-model="config.backgroundImage">
                    <div @click="handleOpenImg('config.backgroundImage', 'background')" slot="append">
                      <i class="iconfont icon-img"></i>
                    </div>
                  </el-input>
                </el-form-item>
                <el-form-item label="预览方式">
                  <el-radio-group v-model="config.screen">
                    <el-radio label="x">X轴铺满，Y轴自适应滚动</el-radio>
                    <el-radio label="y">Y轴铺满，X轴自适应滚动</el-radio>
                    <el-radio label="xy">强行拉伸画面，填充所有视图</el-radio>
                  </el-radio-group>
                </el-form-item>
                <el-form-item label-width="0">
                  <el-button size="small" type="primary" class="block" @click="globShow = true">更多设置</el-button>
                </el-form-item>
              </template>
            </el-form>
          </template>
          <template v-else-if="menuTabs == 1">
            <el-form label-width="120px" label-position="left" size="small">
              <el-form-item label="数据类型">
                <avue-select v-model="activeObj.dataType" :dic="dicOption.dataType"></avue-select>
              </el-form-item>
              <template v-if="isSql">
                <el-form-item label="数据源选择">
                  <avue-select :dic="DIC.sql" v-model="db"></avue-select>
                </el-form-item>

                <el-form-item label="SQL语句" label-position="top">
                  <small @click="sql = `(data)=>{ \n return '' \n}`">函数用法</small>
                  <monaco-editor v-model="sql" language="sql" height="100"></monaco-editor>
                </el-form-item>
              </template>
              <template v-else-if="isApi">
                <el-form-item label="接口地址">
                  <avue-input v-model="activeObj.url"></avue-input>
                </el-form-item>
                <el-form-item label="请求方式">
                  <avue-select v-model="activeObj.dataMethod" :dic="dicOption.dataMethod"></avue-select>
                </el-form-item>
              </template>
              <template v-else-if="isWs">
                <el-form-item label="WS地址">
                  <el-input v-model="activeObj.wsUrl">
                  </el-input>
                </el-form-item>
              </template>
              <template v-else-if="isRecord">
                <el-form-item label="数据集选择">
                  <avue-select :dic="DIC.data" v-model="activeObj.record"></avue-select>
                </el-form-item>
              </template>
              <el-form-item label="刷新时间" v-if="isApi || isWs || isSql || isRecord">
                <avue-input-number v-model="activeObj.time" placeholder="0"></avue-input-number>
              </el-form-item>
              <el-form-item label-width="0">
                <el-button size="small" type="primary" class="block" @click="handleSetting">更多设置</el-button>
              </el-form-item>
              <el-form-item label-width="0">
                <el-button size="small" type="danger" class="block"
                  @click="openCode('stylesFormatter', '编辑样式')">编辑样式</el-button>
              </el-form-item>
              <el-form-item label-width="0">
                <el-button size="small" type="primary" class="block" @click="handleRes">请求数据</el-button>
              </el-form-item>
              <el-form-item label-width="0">
                <monaco-editor v-model="dataRes" disabled height="400"></monaco-editor>
              </el-form-item>
            </el-form>
          </template>
          <template v-else-if="menuTabs == 2">
            <el-form label-width="120px" label-position="left" size="small">
              <el-form-item label="开启数据下钻" v-if="activeObj.name === '饼图'">
                <avue-switch v-model="activeOption.openDrill"></avue-switch>
                  <el-tooltip class="item" effect="dark" content="数据下钻是指当点击当前图表的某条数据时对数据进行逐级钻取" placement="top-start">
                    <span>
                      <i class="el-icon-question" style="color: #fff;font-size: 15px;margin: 5px;"></i>
                    </span>
                  </el-tooltip>
              </el-form-item>
              <el-form-item label="子类">
                <avue-select multiple v-model="activeObj.child.index" :dic="childList" :props="childProps">
                </avue-select>
              </el-form-item>
              <el-form-item label="参数名称">
                <avue-input v-model="activeObj.child.paramName"></avue-input>
              </el-form-item>
              <el-form-item label="映射字段">
                <avue-input v-model="activeObj.child.paramValue" placeholder="默认为value"></avue-input>
              </el-form-item>
              <el-form-item label="其它参数">
                <el-button type="primary" @click="addParamsList">新增参数</el-button>
              </el-form-item>
              <template v-if="activeObj.child.paramList">
                <el-form-item :label="'参数' + (index + 1)" v-for="(item, index) in activeObj.child.paramList" :key="index">
                  <el-form-item label="" label-width="0">
                    <avue-input v-model="item.name" placeholder="参数名称"></avue-input>
                  </el-form-item>
                  <el-form-item label="" label-width="0">
                    <avue-input v-model="item.value" placeholder="映射字段"></avue-input>
                  </el-form-item>
                  <el-button type="danger"
                             @click="delParamsList(index)">删除</el-button>
                </el-form-item>
              </template>
            </el-form>
          </template>
          <template v-else-if="menuTabs == 3">
            <el-form label-width="120px" label-position="left" size="small">
              <el-form-item label="点击事件">
                <el-button size="small" type="primary" @click="openCode('clickFormatter', '点击事件')">编辑</el-button>
              </el-form-item>
              <template v-if="validProp('labelFormatterList')">
                <el-form-item label="提示事件">

                  <el-button size="small" type="primary" @click="openCode('formatter', '提示事件')">编辑</el-button>
                </el-form-item>
                <el-form-item label="标题事件">
                  <el-button size="small" type="primary" @click="openCode('labelFormatter', '标题事件')">编辑</el-button>
                </el-form-item>
              </template>
            </el-form>
          </template>
          <template v-else-if="menuTabs == 4">
            <el-form label-width="90px" label-position="left" v-if="menuTabs == 4" size="small">
              <el-form-item label="序号">
                <avue-input @click.native="handleCopyIndex" v-model="activeIndex" disabled>
                </avue-input>
              </el-form-item>
              <el-form-item label="配置">
                <monaco-editor v-model="activeObj" disabled language="javascript" height="100"></monaco-editor>
              </el-form-item>
              <template v-if="!isFolder">
                <el-form-item label="进入动画">
                  <avue-select filterable allow-create v-model="activeComponent.animated"
                    :dic="dicOption.animated"></avue-select>
                  <div>
                    <a href="https://www.dowebok.com/demo/2014/98/" target="_blank">点击查看动画类型</a>
                  </div>
                </el-form-item>
                <el-form-item label="位置">
                  <div class="flex">
                    <avue-input-number style="width:130px" v-model="activeObj.left"></avue-input-number>
                    &nbsp;x&nbsp;
                    <avue-input-number style="width:130px" v-model="activeObj.top"></avue-input-number>
                  </div>
                </el-form-item>
                <el-form-item label="尺寸">
                  <div class="flex">
                    <avue-input-number style="width:130px" v-model="activeComponent.width"></avue-input-number>
                    &nbsp;x&nbsp;
                    <avue-input-number style="width:130px" v-model="activeComponent.height"></avue-input-number>
                  </div>
                </el-form-item>
                <el-form-item label="字体">
                  <avue-input v-model="activeComponent.fontFamily" placeholder="输入字体库的url">
                  </avue-input>
                </el-form-item>
                <el-form-item label="透视">
                  <avue-slider v-model="activeComponent.perspective" :max="1000"></avue-slider>
                </el-form-item>
                <el-form-item label="缩放">
                  <avue-slider v-model="activeComponent.scale" :max="10"></avue-slider>
                </el-form-item>
                <el-form-item label="透明度">
                  <avue-slider :step="0.1" v-model="activeComponent.opacity" :max="1"></avue-slider>
                </el-form-item>
                <el-form-item label="X旋转度">
                  <avue-slider v-model="activeComponent.rotateX" :min="-360" :max="360"></avue-slider>
                </el-form-item>
                <el-form-item label="Y旋转度">
                  <avue-slider v-model="activeComponent.rotateY" :min="-360" :max="360"></avue-slider>
                </el-form-item>
                <el-form-item label="Z旋转度">
                  <avue-slider v-model="activeComponent.rotateZ" :min="-360" :max="360"></avue-slider>
                </el-form-item>
              </template>
            </el-form>
          </template>
        </el-scrollbar>
      </div>
    </div>
    <codeedit @submit="closeCode" v-if="code.box" :title="code.title" :type="code.type" v-model="code.obj"
      :visible.sync="code.box"></codeedit>
    <el-dialog append-to-body top="1%" title="更多设置" :close-on-click-modal="false" :visible.sync="globShow" width="70%">
      <el-form size="small" label-width="130px">
        <el-form-item label="全局请求地址">
          <avue-input v-model="config.url" placeholder="/"></avue-input>
        </el-form-item>
        <el-form-item label="全局请求参数">
          <monaco-editor v-model="config.query" language="javascript" disabled height="100"></monaco-editor>
          <el-button type="primary" icon="el-icon-edit" @click="openCode('query', '全局请求参数')">编辑</el-button>
        </el-form-item>
        <el-form-item label="全局请求头">
          <monaco-editor v-model="config.header" language="javascript" disabled height="100"></monaco-editor>
          <el-button type="primary" icon="el-icon-edit" @click="openCode('header', '全局请求头')">编辑</el-button>
        </el-form-item>
        <el-form-item label="大屏水印">
          <avue-switch v-model="config.mark.show"></avue-switch>
        </el-form-item>
        <template v-if="config.mark.show">
          <el-form-item label="内容">
            <avue-input v-model="config.mark.text"></avue-input>
          </el-form-item>
          <el-form-item label="大小">
            <avue-input-number v-model="config.mark.fontSize"></avue-input-number>
          </el-form-item>
          <el-form-item label="颜色">
            <avue-input-color v-model="config.mark.color"></avue-input-color>
          </el-form-item>
          <el-form-item label="角度">
            <avue-input-number v-model="config.mark.degree"></avue-input-number>
          </el-form-item>
        </template>
      </el-form>
    </el-dialog>
    <el-dialog append-to-body top="1%" title="更多设置" :close-on-click-modal="false" :visible.sync="show" width="70%">
      <el-form size="small" label-width="130px">
        <el-form-item label="数据类型">
          <avue-select v-model="activeObj.dataType" :dic="dicOption.dataType"></avue-select>
        </el-form-item>
        <template v-if="isStatic">
          <el-form-item label="数据值" label-position="top">
            <el-button size="small" type="primary" icon="el-icon-edit" @click="openCode('data', '数据值')">编辑数据值</el-button>
            &nbsp;
            <el-upload :show-file-list="false" :auto-upload="false" accept=".xls,.xlsx" :on-change="handleImport">
              <el-button size="small" icon="el-icon-upload" type="success">导入数据(Excel)</el-button>
            </el-upload>

          </el-form-item>
        </template>
        <template v-else-if="isSql">
          <el-form-item label="数据源选择">
            <avue-select :dic="DIC.sql" v-model="db"></avue-select>
          </el-form-item>
          <el-form-item label="SQL语句" label-position="top">
            <el-tooltip effect="dark" content="如果要获取变量，直接写成函数返回sql语句即可" placement="top">
              <i class="el-icon-info"></i>
            </el-tooltip>
            <monaco-editor v-model="sql" language="sql" height="100"></monaco-editor>
          </el-form-item>
        </template>
        <template v-else-if="isApi">
          <el-form-item label="接口地址">
            <avue-input v-model="activeObj.url"></avue-input>
          </el-form-item>
          <el-form-item label="请求方式">
            <avue-select v-model="activeObj.dataMethod" :dic="dicOption.dataMethod"></avue-select>
          </el-form-item>
        </template>
        <template v-else-if="isWs">
          <el-form-item label="WS地址">
            <el-input v-model="activeObj.wsUrl">
            </el-input>
          </el-form-item>
        </template>
        <template v-else-if="isRecord">
          <el-form-item label="数据集选择">
            <avue-select :dic="DIC.data" v-model="activeObj.record"></avue-select>
          </el-form-item>
        </template>
        <el-form-item label="请求配置" v-if="isWs || isApi">
          <el-tabs class="menu__tabs" v-model="dataTabs">
            <el-tab-pane label="请求参数（Body）" name="0">
              <template v-if="dataTabs == 0">
                <el-radio-group v-if="['post', 'put'].includes(activeObj.dataMethod)" v-model="activeObj.dataQueryType">
                  <el-radio label="json">JSON数据</el-radio>
                  <el-radio label="form">FORM表单</el-radio>
                </el-radio-group>
                <monaco-editor v-model="activeObj.dataQuery" language="javascript" disabled height="100"></monaco-editor>
                <el-button size="small" type="primary" icon="el-icon-edit"
                  @click="openCode('dataQuery', '请求参数')">编辑</el-button>
              </template>
            </el-tab-pane>
            <el-tab-pane label="请求头（Headers）" name="1" v-if="isApi">
              <template v-if="dataTabs == 1">
                <monaco-editor v-model="activeObj.dataHeader" language="javascript" disabled height="100"></monaco-editor>
                <el-button size="small" type="primary" icon="el-icon-edit"
                  @click="openCode('dataHeader', '请求头')">编辑</el-button>
              </template>
            </el-tab-pane>

          </el-tabs>
        </el-form-item>
        <el-form-item label="过滤器">
          <monaco-editor v-model="activeObj.dataFormatter" language="javascript" disabled height="100"></monaco-editor>
          <el-button size="small" type="primary" icon="el-icon-edit"
            @click="openCode('dataFormatter', '编辑过滤器')">编辑</el-button>

        </el-form-item>
        <el-form-item label="响应数据">
          <monaco-editor v-model="dataRes" disabled height="200"></monaco-editor>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" type="primary" icon="el-icon-refresh" @click="handleRes">请求数据</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>

import MonacoEditor from '@/page/components/editor'
import layer from './group/layer';
import top from './group/top';
import headers from './group/header';
import imglist from './group/imglist'
import contentmenu from './group/contentmenu'
import codeedit from './group/code';
import { dicOption } from '@/option/config'
import init from '@/mixins/'
import { createFile, uuid } from '@/utils/utils'
import components from '@/option/components'
import SketchRule from "vue-sketch-ruler";
import { getList as getDbList } from "@/api/db";
import { getList as getRecordList } from "@/api/record";

export default {
  mixins: [init, components],
  data() {
    return {
      layerType: 0,
      currentHistoryIndex: -1,
      menuId: 'avue-data-menu',
      menuShow: true,
      paramsShow: true,
      globShow: false,
      show: false,
      cacheList: {
        timer: null,
        nav: null,
        copy: null,
        history: []
      },
      keys: {
        ctrl: false
      },
      dataRes: '',
      db: '',
      sql: '',
      nav: [],
      DIC: {
        sql: [],
        data: []
      },
      loading: '',
      childProps: {
        label: 'name',
        value: 'index'
      },
      key: '',
      menuParams: {
        menuWidth: 200,
        paramsWidth: 330,
      },
      menuFlag: true,
      code: {
        title: '',
        box: false,
        type: '',
        obj: '',
      },
      form: {},
      dicOption: dicOption,
      menuTabs: 0,
      dataTabs: 0,
      // 标尺
      width: document.body.clientWidth - 550,
      height: document.body.clientHeight - 104,
      scale: 0.94,
      startX: 0,
      startY: 0,
      palette: {
        bgColor: '#18181c',
        longfgColor: '#BABBBC',
        shortfgColor: '#9C9C9C',
        fontColor: '#fff',
        shadowColor: '#18181c',
        lineColor: '#EB5648',
        borderColor: '#B5B5B5',
        cornerActiveColor: '#fff',
      },
      lines: {
        h: [],
        v: []
      },
      thick: 20,
      isShowReferLine: true,
      imgOpenData: '', // 左上角图片
      imgClose: '',
    }
  },
  components: {
    MonacoEditor,
    imglist,
    layer,
    codeedit,
    top,
    headers,
    contentmenu,
    SketchRule
  },
  computed: {
    isMain() {
      return this.isActive && !this.isSelectActive
    },
    scrollStyleName() {
      let calc = this.setPx(!this.isMain ? 50 : 85)
      return { paddingTop: calc }
    },
    shadow() {
      return {
        x: 0,
        y: 0,
        width: this.width,
        height: this.height
      }
    },
    // 能否撤销
    canUndo() {
      return this.currentHistoryIndex > 0
    },
    canRedo() {
      return this.cacheList.history.length > this.currentHistoryIndex + 1
    },
    isKeysCtrl() {
      return this.keys.ctrl == true
    },
    isStatic() {
      return this.activeObj.dataType == 0
    },
    isApi() {
      return this.activeObj.dataType == 1
    },
    isSql() {
      return this.activeObj.dataType == 2
    },
    isWs() {
      return this.activeObj.dataType === 3
    },
    isRecord() {
      return this.activeObj.dataType == 4
    },
    isFolder() {
      return this.activeObj.children
    },
    isActive() {
      return this.activeIndex
    },
    isSelectActive() {
      return this.active.length > 1;
    },
    childList() {
      return this.list.filter(ele => {
        if (ele.children) return false
        let component = ele.component || {}
        return !['tabs'].includes(component.prop);
      })
    },
    activeComponent() {
      return this.activeObj.component || {}
    },
    activeOption() {
      return this.activeObj.option || {}
    },
    activeObj() {
      let item = this.findList(this.activeIndex) || {}
      if (!item.child) item.child = {}
      return item
    },
    activeList() {
      let result = []
      this.active.forEach(ele => {
        let item = this.findnav(ele);
        result.push(item.item);
      })
      return result
    },

    canvasStyle() {
      return {
        width: this.setPx(this.width),
        height: this.setPx(this.height),
        transform: `scale(${this.scale})`
      }
    }
  },
  watch: {
    nav: {
      handler(val, old) {
        this.recordHistoryCache(val)
      },
      deep: true
    },
    'activeObj.dataType'() {
      this.dataTabs = '0'
    },
    activeObj: {
      handler(val) {
        if (this.activeObj.sql && this.isSql) {
          let mode = this.activeObj.sql;
          this.db = mode.id;
          this.sql = mode.sql;
        } else {
          this.db = '';
          this.sql = '';
        }
      },
      deep: true
    },
    activeOverIndex(n, o) {
      [o, n].forEach((ele, index) => {
        if (!ele) return
        this.setActive(ele, index === 1, 'setOverActive');
      })
    },
    active(n, o) {
      [o, n].forEach((ele, index) => {
        ele.forEach(item => {
          this.setActive(item, index === 1, 'setActive');
        })
      })
      // 初始化选项卡
      this.menuTabs = '0';
    },
  },
  created() {
    this.initDataList();
  },
  mounted() {
    setTimeout(() => {
      this.initFun()
      this.initSize()
      this.listenKey();
    })
  },
  methods: {
    delParamsList (index) {
      this.activeObj.child.paramList.splice(index, 1)
    },
    addParamsList() {
      if (!this.activeObj.child.paramList) {
        this.$set(this.activeObj.child, 'paramList', [])
      }
      this.activeObj.child.paramList.push({
        name: '',
        value: ''
      })
    },
    handleDrag(e, name) {
      let resize = this.$refs[name + 'Drag']
      if (!resize) return
      let startX = e.clientX;
      document.onmousemove = (e) => {
        let endX = e.clientX;
        let moveLen = endX - startX;
        startX = endX;
        this.menuParams[name + 'Width'] += name == 'params' ? -moveLen : moveLen
        this.$refs.headers.handleSet()
      };
      document.onmouseup = () => {
        document.onmousemove = null;
        document.onmouseup = null;
      };
      return false;
    },
    handleCopyIndex() {
      this.$Clipboard({
        text: this.activeObj.index
      }).then(() => {
        this.$message.success('复制成功')
      }).catch(() => {
        this.$message.error('复制失败')
      });
    },
    handleTabClick(tab) {
      if (tab.name == '1') {
        this.handleRes(false)
      }
    },
    handleImport(file, fileLis) {
      this.$Export.xlsx(file.raw)
        .then(data => {
          this.activeObj.data = data.results;
          this.$message.success('导入成功')
          this.handleRes()
        })
    },
    handleRefresh() {
      return this.$refs.container.handleRefresh();
    },
    handleRes(tip = true) {
      if (this.isSql) {
        this.$set(this.activeObj, 'sql', {
          id: this.db,
          sql: this.sql
        })
      }
      this.handleRefresh().then((res = {}) => {
        console.log("res", res)
        if (!this.validatenull(res)) {
          this.dataRes = JSON.stringify(res, null, 4);
        } else {
          this.dataRes = '';
        }
        if (tip) this.$message.success('请求数据成功')

      })
    },
    handleParams(type, obj) {
      const deepList = (list, flag) => {
        list.forEach(ele => {
          ele[type] = flag
          if (ele.children) deepList(ele.children, flag);
        })
      }
      if (obj) {
        obj[type] = !obj[type]
        deepList([obj], obj[type])
      } else {
        this.active.forEach(ele => {
          let { item } = this.findnav(ele)
          item[type] = !item[type]
          deepList([item], item[type])
        })
      }
      this.handleInitActive()
    },
    handleSetting() {
      this.dataTabs = 0
      this.dataRes = '';
      this.handleRes(false)
      this.show = true;
    },
    initDataList() {
      getDbList({
        pageNum: 1,
        pageSize: 100,
      }).then(res => {
        const data = res.rows;
        this.DIC.sql = data.map(ele => {
          return {
            label: ele.name,
            value: ele.uuid
          }
        })
      });
      getRecordList({
        pageNum: 1,
        pageSize: 100,
      }).then(res => {
        const data = res.rows;
        this.DIC.data = data.map(ele => {
          return {
            label: ele.name,
            value: ele.uuid
          }
        })
      });
    },
    closeCode(value) {
      if (this.configData.includes(this.code.type)) {
        this.config[this.code.type] = value;
      } else {
        this.activeObj[this.code.type] = value;
      }
      this.handleRes(false)
    },
    openCode(type, title) {
      this.code.type = type;
      this.code.title = title
      if (this.configData.includes(type)) {
        this.code.obj = this.config[type];
      } else {
        this.code.obj = this.activeObj[type];
      }
      this.code.box = true;
    },
    initFun() {
      ['setScale'].forEach(ele => {
        this[ele] = this.$refs.container[ele]
      })
    },
    // 右键菜单
    handleContextMenu(item = {}, done) {
      if (!item.index || this.isKeysCtrl) return
      else if (!this.isSelectActive) {
        this.active = [item.index];
        this.activeIndex = item.index;
      }
      done()
    },
    //监听键盘的按键
    listenKey() {
      let section = this.$refs.section;
      section.onkeydown = (e) => {
        const keyCode = e.keyCode;
        e.preventDefault();
        if (keyCode == 17) {
          this.keys.ctrl = true
        } else if (keyCode == 76 && this.isKeysCtrl) {
          if (!this.activeObj) return
          this.handleParams('lock')
          this.handleInitActive()
        } else if (keyCode == 67 && this.isKeysCtrl) {
          if (!this.activeObj) return
          this.$refs.contentmenu.handleCopy((fn) => {
            this.cacheList.copy = fn
            this.$message.success('复制组件成功')
          })
        } else if (keyCode == 86 && this.isKeysCtrl) {
          if (!this.cacheList.copy) return
          let active = []
          let { itemList } = this.findnav(this.activeIndex)
          itemList = itemList;
          this.cacheList.copy.forEach(ele => {
            active = active.concat(ele(itemList))
          })
          setTimeout(() => this.selectNav(active))
          this.$message.success('粘贴组件成功')
        } else if (keyCode == 90 && this.isKeysCtrl) {
          this.editorUndo()
        } else if (keyCode == 89 && this.isKeysCtrl) {
          this.editorRedo()
        } else if (keyCode == 83 && this.isKeysCtrl) {
          this.$refs.headers.handleBuild();
        } else if (keyCode == 8 || keyCode == 46) {
          this.$refs.contentmenu.handleDel();
        }
      }
      section.onkeyup = (e) => {
        const keyCode = e.keyCode;
        if (keyCode == 17) {
          this.keys.ctrl = false
        }
      }
    },
    setActive(val, result, fun) {
      const obj = this.$refs.container.getListRef(val);
      if (obj) obj[fun](result)
    },
    //批量成组
    handleFolder() {
      let folder = createFile()
      this.active.forEach(index => {
        let { itemList, itemIndex } = this.findnav(index);
        let obj = itemList.splice(itemIndex, 1)[0];
        folder.children.push(obj);
      })
      this.nav.push(folder);
      this.handleInitActive();
    },
    //批量删除
    handleDeleteSelect() {
      this.$confirm(`是否批量删除所选图层?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.active.forEach(index => {
          let { itemList, itemIndex } = this.findnav(index);
          itemList.splice(itemIndex, 1);
        })
        this.handleInitActive()
      })
    },
    validProp(name) {
      return this.dicOption[name].includes(this.activeComponent.prop)
    },
    formatTooltip(val) {
      return parseInt(val);
    },
    //打开图库
    handleOpenImg(item, type) {
      this.$refs.imglist.openImg(item, type);
    },
    //图库框回调赋值
    handleSetimg(val, type) {
      let params = type.split('.')[1];
      if (type.includes('config')) {
        this.config[params] = val;
      } else if (type.includes('activeObj.data.value')) {
        this.activeObj.data.value = val;
      } else if (type.includes('activeObj.data')) {
        this.activeObj.data = val;
      } else if (type.includes('activeObj')) {
        this.activeObj[params] = val;
      } else if (type.includes('activeOption')) {
        this.activeOption[params] = val;
      }
    },

    handleScroll() {
      this.$nextTick(() => {
        const screensRect = this.$refs.screensRef.getBoundingClientRect();
        const canvasRect = this.$refs.canvas.getBoundingClientRect();
        // 标尺开始的刻度
        const startX = (screensRect.left + this.thick - canvasRect.left) / this.scale;
        const startY = (screensRect.top + this.thick - canvasRect.top) / this.scale;
        this.startX = startX >> 0;
        this.startY = startY >> 0;

      })
    },
    // 控制缩放值
    handleWheel(e) {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault();
        const nextScale = parseFloat(
          Math.max(0.2, this.scale - e.deltaY / 500).toFixed(2)
        );
        this.scale = nextScale;
      }
      this.$nextTick(() => {
        this.handleScroll();
      });
    },
    // 初始化标尺数值
    initSize() {
      // 滚动居中
      let containerRect = this.$refs.containerRef.getBoundingClientRect()
      let screensRect = this.$refs.screensRef.getBoundingClientRect()
      this.$refs.screensRef.scrollLeft = containerRect.width / 2 - 10
      this.$refs.screensRef.scrollTop = containerRect.height / 2 - 50
    },
    // 图片点击事件
    imgClick() {
      this.isShowReferLine = !this.isShowReferLine
    },
    selectNav(item) {
      if (this.isKeysCtrl) {
        if (Array.isArray(item)) {
          this.active = this.active.concat(item)
        } else {
          this.active.push(item);
        }
      } if (Array.isArray(item)) {
        this.active = item;
        this.activeIndex = item[item.length - 1];
      } else if (this.active.includes(item)) {
        this.activeIndex = item;
      } else {
        this.active = [item];
        this.activeIndex = item;
      }
    },
    recordHistoryCache(val) {
      const debounce = (func, delay) => {
        return () => {
          let context = this;
          let args = arguments;
          clearTimeout(this.cacheList.timer);
          this.cacheList.timer = setTimeout(() => {
            func.apply(context, args);
          }, delay);
        }
      }
      const callback = () => {
        let nav = JSON.stringify(val)
        if (nav != this.cacheList.nav) {
          this.cacheList.nav = nav
          this.addHistoryCache(val)
        }
      }
      debounce(callback, 300)()
    },
    addHistoryCache(val) {
      if (this.currentHistoryIndex + 1 < this.cacheList.history.length) {
        this.cacheList.history.splice(this.currentHistoryIndex + 1)
      }
      this.cacheList.history.push({
        nav: this.deepClone(val),
      })
      this.cacheList.history.splice(100)
      this.currentHistoryIndex++
    },
    editorUndo() {
      if (!this.canUndo) return
      this.currentHistoryIndex--
      this.recoveryHistoryCache()
    },
    editorRedo() {
      if (!this.canRedo) return;
      this.currentHistoryIndex++
      this.recoveryHistoryCache()
    },
    recoveryHistoryCache() {
      const prevState = this.cacheList.history[this.currentHistoryIndex]
      this.nav = this.deepClone(prevState.nav)
      this.cacheList.nav = JSON.stringify(prevState.nav)
    }
  }
}
</script>
<style lang="scss">
@import "../styles/style.scss";

.refer-line-img {
  position: absolute;
  left: 0;
  z-index: 5;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;

  img {
    width: 100%;
  }
}

.screens {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
}

.screen-container {
  position: relative;
  width: 5000px;
  height: 3000px;
  background: url("/img/screen.png") repeat;
}

.dragghanle {
  cursor: pointer;
}

.canvas {
  position: absolute;
  top: 50%;
  left: 50%;
}

.section {
  flex: 1;
  overflow: hidden;
  position: relative;
}
</style>
